package com.example.yue.appclent.client;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

public class ClientRunable implements Runnable {
    private final String host;
    private final int port;
    private Socket socket;
    /**
     * 定义向UI线程发送消息的Handler对象
     */
    private Handler handler;
    /**
     * 定义接收UI线程的Handler对象
     */
    private Handler revHandler;
    // 该线程处理Socket所对用的输入输出流
    BufferedReader br = null;
    OutputStream os = null;

    private boolean closeFlag;


    public ClientRunable(Handler handler, String host, int port) {
        this.handler = handler;
        this.host = host;
        this.port = port;
    }

    @Override
    public void run() {

            socket = new Socket();
            try {
                socket.connect(new InetSocketAddress(host, port), 5000);
                br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
                os = socket.getOutputStream();
                // 启动一条子线程来读取服务器相应的数据
                new Thread() {
                    @Override
                    public void run() {
                        if (!closeFlag) {
                            String content = null;
                            // 不断的读取Socket输入流的内容
                            try {
                                while ((content = br.readLine()) != null) {
                                    // 每当读取到来自服务器的数据之后，发送的消息通知程序
                                    // 界面显示该数据
                                    Message msg = new Message();
                                    msg.what = Contast.MESS_FROM_RUN;
                                    msg.obj = content;
                                    handler.sendMessage(msg);
                                }
                            } catch (IOException io) {
                                io.printStackTrace();
                                sendException(io);
                            }
                        }
                    }
                }.start();
                // 为当前线程初始化Looper
                Looper.prepare();
                // 创建revHandler对象
                revHandler = new Handler() {

                    @Override
                    public void handleMessage(Message msg) {
                        // 接收到UI线程的中用户输入的数据
                        if (msg.what == Contast.MESS_FROM_UI) {
                            // 将数据发送到指定网络
                            try {
                                String messJson = msg.obj.toString();
                                //服务器按行读取。。。不加，流无法读取
                                if (!messJson.endsWith("\n") && !messJson.endsWith("\r")){
                                    messJson = messJson+"\n";
                                }
                                Log.d(">>>","发送到服务器："+messJson);
                                os.write(messJson.getBytes("utf-8"));
                                os.flush();
                            } catch (Exception e) {
                                e.printStackTrace();
                                sendException(e);
                            }
                        }
                    }
                };
                // 启动Looper
                Looper.loop();

            } catch (SocketTimeoutException e) {
                sendMess("网络连接超时！");
            } catch (IOException io) {
                io.printStackTrace();
                sendException(io);
            }
    }
    private <Ex extends Exception> void sendException(Ex ex){
        Message msg = new Message();
        msg.what = Contast.MESS_FROM_RUN;
        msg.obj = ex.getMessage();
        handler.sendMessage(msg);
    }
    private void sendMess(CharSequence charSequence){
        Message msg = new Message();
        msg.what = Contast.MESS_FROM_RUN;
        msg.obj = charSequence;
        handler.sendMessage(msg);
    }

    public void sendMess(Message mess) {
        if (revHandler != null) {
            revHandler.sendMessage(mess);
        }
    }

    public void close() {
        this.closeFlag = true;
    }
    public void reValid(){
        this.closeFlag = false;
    }
}
